home *** CD-ROM | disk | FTP | other *** search
- /* demodes.c: jl 30 April 1986: demonstrate DES in various modes */
-
- /* this uses a version of DES that is driven directly */
- /* from the NBS tables (including E) and hence is rather slow */
- /* (100ms to encrypt a block on a C/70). */
- /* it is fairly compact. */
-
- /* key schedule code (from dumbksb.c) does not use the pc2 optimization */
- /* and outputs a key schedule as an array of longs */
- /* where each long contains a 24-bit right-justified */
- /* quantity, compatible with unoptimized e */
-
- #ifdef BBN
- # include <style.h>
- #else
- # define TRUE 1
- # define FALSE 0
- #endif
- #include <stdio.h>
- #include <ctype.h>
-
- /* --- some bit manipulation primitives --- */
-
- /* g_bit -- extract bit bnum from a byte.
- As per NBS, MSB is bit 1, LSB bit 8 */
- int g_bit (bnum, byte)
- int bnum;
- unsigned byte;
- {
- byte &= 0XFF;
- return (01 & (byte >> (8 - bnum)) );
- }
-
- int gb_f28 (bnum, lval)
- /* get the bnum bit from 28-bit lval */
- int bnum;
- long lval;
- {
- return (01 & (lval >> (28 - bnum)) );
- }
-
-
- /* --- following code and data does key schedule generation --- */
- #define NINPC1 28
- #define NINPC2 48
- #define PC2FRR 24 /* number of output bits from C or D */
- #define SUCCESS 0 /* return values from ksmake */
- #define FAILURE 1
-
- int ksmake (inkey, ks) /* Make a key schedule from key bytes in inkey */
- /* result is SUCCESS if OK, FAILURE otherwise */
- unsigned inkey [8];
- long ks [16] [2];
- {
- static int pc1c [] =
- { 57, 49, 41, 33, 25, 17, 9,
- 1, 58, 50, 42, 34, 26, 18,
- 10, 2, 59, 51, 43, 35, 27,
- 19, 11, 3, 60, 52, 44, 36 };
-
- static int pc1d [] =
- { 63, 55, 47, 39, 31, 23, 15,
- 7, 62, 54, 46, 38, 30, 22,
- 14, 6, 61, 53, 45, 37, 29,
- 21, 13, 5, 28, 20, 12, 4 };
-
- static int shiftsked []=
- { 1, 1, 2, 2, 2, 2, 2, 2,
- 1, 2, 2, 2, 2, 2, 2, 1 };
-
- static int pc2 [] =
- { 14, 17, 11, 24, 1, 5,
- 3, 28, 15, 6, 21, 10,
- 23, 19, 12, 4, 26, 8,
- 16, 7, 27, 20, 13, 2,
- 41, 52, 31, 37, 47, 55,
- 30, 40, 51, 45, 33, 48,
- 44, 49, 39, 56, 34, 53,
- 46, 42, 50, 36, 29, 32 };
-
- int i, j, parac, round, nshifts;
- long pcc, pcd;
- unsigned incopy;
-
- /* first check parity */
- for (i = 0; i < 8; i++) /* do each byte */
- {
- parac = 0;
- incopy = inkey [i];
-
- for (j = 0; j < 8; j++) /* 8 bits in a DES byte */
- {
- if (incopy & 01) parac++;
- incopy >>= 1;
- }
- if (! (parac & 01)) return (FAILURE); /* no odd parity on this byte */
- }
-
- /* now do pc1 permutation */
- pcc = pcd = 0L;
- for (i = 0; i < NINPC1; i++) /* filling all appropriate bits */
- {
- pcc |= (01 & g_bit (pc1c [i] % 8, (unsigned) (inkey [pc1c [i] / 8])));
- pcd |= (01 & g_bit (pc1d [i] % 8, (unsigned) (inkey [pc1d [i] / 8])));
- if (i != (NINPC1 - 1)) /* avoid superfluous final shift */
- {
- pcc <<= 1;
- pcd <<= 1;
- }
- }
-
- for (round = 0; round < 16; round++)
- {
- for (nshifts = 0; nshifts < shiftsked [round]; nshifts++)
- {
- /* do appropriate number of 28-bit left rotates on pcc, pcd */
- pcc <<= 1;
- if (0X10000000L & pcc) pcc++;
- pcc &= 0XFFFFFFFL;
- pcd <<= 1;
- if (0X10000000L & pcd) pcd++;
- pcd &= 0XFFFFFFFL;
- }
-
- /* Now, pcc and pcd have the values on which we can apply
- pc2 and select the key bits, storing them in ks[0] and
- ks[1]. The high order [ks[0]] bits all come from
- pcc, and the low order from pcd. */
-
- ks [round] [0] = ks [round] [1] = 0;
- for (i = 0; i < PC2FRR; i++)
- {
- ks [round] [0] |= gb_f28 (pc2 [i], pcc);
- if (i != (PC2FRR - 1)) ks [round] [0] <<= 1;
- }
- for (i = PC2FRR; i < NINPC2; i++)
- {
- ks [round] [1] |= gb_f28 (pc2 [i] - NINPC1, pcd);
- if (i != (NINPC2 - 1)) ks [round] [1] <<= 1;
- }
- }
- return (SUCCESS);
- }
-
- #define IP 1 /* flag to select IP */
- #define IPI IP+1 /* flag to select IPI */
- #define ENCRYPT IPI+1 /* flag to select encryption */
- #define DECRYPT ENCRYPT+1 /* flag to select decryption */
-
- /* dop -- permute 64 bits via choice of IP or IPI */
- dop (inar, outar, flag)
- long inar [2];
- long outar [2];
- int flag;
- {
- static int ip [64] =
- { 58, 50, 42, 34, 26, 18, 10, 2,
- 60, 52, 44, 36, 28, 20, 12, 4,
- 62, 54, 46, 38, 30, 22, 14, 6,
- 64, 56, 48, 40, 32, 24, 16, 8,
- 57, 49, 41, 33, 25, 17, 9, 1,
- 59, 51, 43, 35, 27, 19, 11, 3,
- 61, 53, 45, 37, 29, 21, 13, 5,
- 63, 55, 47, 39, 31, 23, 15, 7};
-
- static int ipi [64] =
- { 40, 8, 48, 16, 56, 24, 64, 32,
- 39, 7, 47, 15, 55, 23, 63, 31,
- 38, 6, 46, 14, 54, 22, 62, 30,
- 37, 5, 45, 13, 53, 21, 61, 29,
- 36, 4, 44, 12, 52, 20, 60, 28,
- 35, 3, 43, 11, 51, 19, 59, 27,
- 34, 2, 42, 10, 50, 18, 58, 26,
- 33, 1, 41, 9, 49, 17, 57, 25};
-
- int i;
-
- outar [0] = outar [1] = 0L;
- for (i = 1; i < 33; i++)
- {
- outar [0] |= 01 & ((((flag == IP) ? ip[i-1] : ipi[i-1]) < 33) ?
- (inar [0] >> (32 - ((flag == IP) ? ip[i-1] : ipi[i-1]))) :
- (inar [1] >> (64 - ((flag == IP) ? ip[i-1] : ipi[i-1]))) );
- if (i != 32) outar [0] <<= 1;
- }
- for (i = 33; i < 65; i++)
- {
- outar [1] |= 01 & ((((flag == IP) ? ip[i-1] : ipi[i-1]) < 33) ?
- (inar [0] >> (32 - ((flag == IP) ? ip[i-1] : ipi[i-1]))) :
- (inar [1] >> (64 - ((flag == IP) ? ip[i-1] : ipi[i-1]))) );
- if (i != 64) outar [1] <<= 1;
- }
- }
-
- /* dodes -- encrypt or decrypt a block under key sched in ks */
- dodes (inar, outar, flag, ks)
- long inar [2];
- long outar [2];
- int flag;
- long ks [16] [2];
- {
- /* tables to define S boxes and P, per NBS */
-
- static int s_table [8] [4] [16] =
- { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
- 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
- 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
- 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
-
- 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
- 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
- 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
- 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
-
- 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
- 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
- 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
- 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
-
- 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
- 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
- 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
- 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
-
- 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
- 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
- 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
- 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
-
- 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
- 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
- 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
- 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
-
- 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
- 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
- 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
- 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
-
- 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
- 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
- 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
- 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 };
-
- static int ptab [32] =
- { 16, 7, 20, 21,
- 29, 12, 28, 17,
- 1, 15, 23, 26,
- 5, 18, 31, 10,
- 2, 8, 24, 14,
- 32, 27, 3, 9,
- 19, 13, 30, 6,
- 22, 11, 4, 25 };
-
- static int etab [48] =
- { 32, 1, 2, 3, 4, 5,
- 4, 5, 6, 7, 8, 9,
- 8, 9, 10, 11, 12, 13,
- 12, 13, 14, 15, 16, 17,
- 16, 17, 18, 19, 20, 21,
- 20, 21, 22, 23, 24, 25,
- 24, 25, 26, 27, 28, 29,
- 28, 29, 30, 31, 32, 1};
-
- register int round, sb, sbidx, i, j;
- long expan [2]; /* receives output of E transform */
- long sbout, scopy;
- long oarr [2];
-
- dop (inar, outar, IP);
-
- for (round = 0; round < 16; round++)
- {
- /* first perform des e transformation of 32->48 bits.
- accepts an input long, returns result into an array of two longs
- with 24 low-order bits in each element */
- expan [0] = expan [1] = 0L;
- for (i = 1; i < 25; i++)
- {
- expan [0] |= 01 & (outar [1] >> (32 - etab[i-1]));
- if (i != 24) expan [0] <<= 1;
- }
- for (i = 25; i < 49; i++)
- {
- expan [1] |= 01 & (outar [1] >> (32 - etab[i-1]));
- if (i != 48) expan [1] <<= 1;
- }
- /* xor expanded quantity with key schedule */
- expan [0] ^= ks [(flag == ENCRYPT) ? round : 15 - round] [0];
- expan [1] ^= ks [(flag == ENCRYPT) ? round : 15 - round] [1];
- scopy = 0L;
- for (sb = 0; sb < 8; sb++)
- { /* look up bits in s-boxes, filling a 32 bit word */
- sbidx = 0X3F & ((sb < 4) ?
- (expan [0] >> (18 - (6 * sb))) : (expan [1] >> (18 - (6 * (sb-4)))) );
- /* select bits per nbs spec */
- i = sbidx; i &= 0X20; i >>= 4; i |= 01 & sbidx;
- j = sbidx; j &= 0X1E; j >>= 1;
- scopy |= s_table [sb] [i] [j];
- if (sb != 7) scopy <<= 4;
- }
- /* now, perform p permutation into 'sbout' */
- sbout = 0L;
- for (i = 1; i < 33; i++)
- {
- sbout |= 01 & (scopy >> (32 - ptab [i-1]));
- if (i != 32) sbout <<= 1;
- }
-
- scopy = outar [0];
- outar [0] = outar [1];
- outar [1] = scopy ^ sbout;
- }
-
- /* a final swap into temp copy - let dop move into true output array */
- scopy = outar [0];
- oarr [0] = outar [1];
- oarr [1] = scopy;
- dop (oarr, outar, IPI);
- }
-
- /* support routines for demodes */
-
- /* read input bytes from stdin */
- int g_inbytes (nby, buffer) /* returns TRUE iff EOF reached */
- int nby; /* number of bytes needed at a time */
- /* if insufficient, will be padded with nulls */
- char buffer [];
- {
- int bufix;
- int getcval;
-
- /* init all significant bytes to null pad */
- for (bufix = 0; bufix < nby; bufix++) buffer[bufix] = 0;
-
- for (bufix = 0; bufix < nby; bufix++)
- {
- getcval = getchar ();
- buffer [bufix] = (char) getcval;
- if (getcval == EOF)
- {
- buffer[bufix] = 0; /* replace with pad */
- return (TRUE); /* indicating that EOF detected */
- }
- }
- return (FALSE); /* indicating no EOF detected */
- }
-
- /* represent a series of bytes (conditionally) in two buffers, as
- printable representation and hex representation */
- di_bytes (nby, inbuf, pr_buf, hx_buf)
- int nby;
- char inbuf [];
- char pr_buf []; /* NULL if not desired */
- char hx_buf []; /* NULL if not desired */
- {
- int i;
-
- for (i = 0; i < nby; i++)
- {
- if (pr_buf != NULL)
- {
- /* Try to show as a printable character, either directly or */
- /* by masking off the MSB (if the latter, prefix with '#') */
- if (inbuf [i] > 0x7f)
- {
- if (isprint (inbuf [i] & 0x7f))
- sprintf (pr_buf, "#%c", inbuf [i] & 0x7f);
- else sprintf (pr_buf, " ");
- }
- else
- {
- if (isprint (inbuf [i]))
- sprintf (pr_buf, " %c", inbuf [i]);
- else sprintf (pr_buf, " ");
- }
- pr_buf += 2;
- }
- if (hx_buf != NULL)
- {
- sprintf (hx_buf, "%1x%1x", 0xf & (inbuf[i]>>4),0xf & inbuf [i]);
- hx_buf += 2;
- }
- }
- if (pr_buf != NULL) sprintf (pr_buf, "|");
- if (hx_buf != NULL) sprintf (hx_buf, "|");
- }
-
- packbtol (as_ba, as_l) /* pack 4 bytes into a long */
- char as_ba [];
- long *as_l;
- {
- long lt;
-
- lt = as_ba [0] & 0xff;
- lt <<= 8;
- lt |= as_ba [1] & 0xff;
- lt <<= 8;
- lt |= as_ba [2] & 0xff;
- lt <<= 8;
- lt |= as_ba [3] & 0xff;
-
- *as_l = lt;
- }
-
- sprdltob (as_l, as_ba) /* spread a long into 4 bytes */
- long as_l;
- char as_ba [];
- {
- as_ba [0] = (char) ((as_l >> 24) & 0xff);
- as_ba [1] = (char) ((as_l >> 16) & 0xff);
- as_ba [2] = (char) ((as_l >> 8) & 0xff);
- as_ba [3] = (char) (as_l & 0xff);
- }
-
- lsh64 (lar, count) /* left shift a 64-bit quantity maintained */
- long lar[]; /* in a 2-element long array. Assumes that */
- int count; /* a long has at least 32 bits */
- {
- int i;
- long t;
-
- for (i = 0; i < count; i++)
- {
- t = (lar [1] >> 31) & 0x1l;
- lar [1] <<= 1;
- lar [0] <<= 1;
- lar [0] |= t;
- }
- lar [0] &= 0xffffffffl;
- lar [1] &= 0xffffffffl;
- }
-
- rsh64 (lar, count) /* right shift a 64-bit quantity maintained */
- long lar[]; /* in a 2-element long array. Assumes that */
- int count; /* a long has at least 32 bits */
- {
- int i;
- long t;
-
- for (i = 0; i < count; i++)
- {
- t = lar [0] & 0x1l;
- lar [1] >>= 1;
- lar [0] >>= 1;
- lar [1] |= (t << 31);
- }
- }
-
- rplr64 (base, modr, nbits) /* replace rightmost nbits of base */
- long base[]; /* (64-bit qty in 2-elmt long array) */
- long modr[]; /* with corresponding bits from modr */
- int nbits;
- { /* Assumes longs are 32 bits or more */
- long mask;
- long lmod; /* local copy of modr word */
-
- mask = (nbits >= 32) ? 0xffffffffl : ((0x1l << nbits) - 1);
- /* mask = (0x1l << ((nbits > 32) ? 32 : nbits)) - 1; */
- base [1] &= ~mask; /* wipe out existing low bits */
- lmod = modr [1] & mask;
- base [1] |= lmod;
-
- nbits -= 32;
- if (nbits <= 0) return;
-
- mask = (0x1l << nbits) - 1;
- base [0] &= ~mask;
- lmod = modr [0] & mask;
- base [0] |= lmod;
- }
-
- cpy64 (src, dest) /* copy src 2-elmt long array to dest */
- long src[];
- long dest[];
- {
- dest [0] = src [0];
- dest [1] = src [1];
- }
-
- #define ECB 1
- #define CBC ECB+1
- #define OFB CBC+1
- #define CFB OFB+1
-
- main (argc,argv)
- int argc;
- char *argv [];
- {
- int argn;
- int dmode;
- int eofyet = FALSE; /* will set to TRUE when end of input */
- int quant = 0; /* quantum size (in bits) for selected mode */
- int flwid; /* size to display a 64-bit chunk of pt or ct */
- int i, j;
- long iv [2], keyl [2];
-
- unsigned inkey [8];
- char inkeyc [8];
- char inbbuf [8], otbbuf [8];
- char iprline [80], ihxline [80], ohxline [80];
- long ks [16] [2];
-
- long plain [2], crypt [2], cprbuf [2], cipher [2];
-
- /* default key and IV to NBS sample values */
- keyl [0] = 0x01234567l;
- keyl [1] = 0x89abcdefl;
- iv [0] = 0x12345678l;
- iv [1] = 0x90abcdefl;
-
- /* scan the command line */
- for (argn = 1; argn <= argc; argn++)
- {
- if (seq_nocase (argv[argn], "-m")) /* mode specifier */
- { /* one string argument expected */
- argn++;
- if (seq_nocase (argv[argn], "ecb"))
- {
- dmode = ECB; quant = 64;
- }
- else if (seq_nocase (argv[argn], "cbc"))
- {
- dmode = CBC; quant = 64;
- }
- else if (seq_nocase (argv[argn], "ofb"))
- {
- dmode = OFB; if (quant == 0) quant = 64; /* may be overridden */
- }
- else if (seq_nocase (argv[argn], "cfb"))
- {
- dmode = CFB; if (quant == 0) quant = 64; /* may be overridden */
- }
- }
- else if (seq_nocase (argv[argn], "-k")) /* key specifier */
- { /* two long hex numerics expected */
- argn++;
- sscanf (argv[argn], "%lx", &keyl [0]);
- argn++;
- sscanf (argv[argn], "%lx", &keyl [1]);
- }
- else if (seq_nocase (argv[argn], "-iv")) /* IV specifier */
- { /* two long hex numerics expected */
- argn++;
- sscanf (argv[argn], "%lx", &iv [0]);
- argn++;
- sscanf (argv[argn], "%lx", &iv [1]);
- }
- else if (seq_nocase (argv[argn], "-q")) /* quantum specifier */
- { /* one decimal number expected */
- argn++;
- sscanf (argv[argn], "%d", &quant);
- }
- }
-
- if (((dmode == ECB) || (dmode == CBC)) && (quant != 64))
- {
- printf ("Can't override quantum of 64 for ECB or CBC modes... aborting\n");
- exit (1);
- }
-
- /* build key schedule (outside scanner, so default works) */
- sprdltob (keyl [0], & inkeyc [0]);
- sprdltob (keyl [1], & inkeyc [4]);
- for (i = 0; i < 8; i++) inkey [i] = (unsigned) (inkeyc [i] & 0xff);
- if (ksmake (inkey, ks) != SUCCESS)
- {
- printf ("Bad parity on key... aborting...\n");
- exit (1);
- }
-
- printf ("Mode is ");
- switch (dmode)
- {
- case ECB:
- printf ("ECB;");
- break;
- case CBC:
- printf ("CBC;");
- break;
- case OFB:
- printf ("OFB;");
- printf (" Quantum is %d;", quant);
- break;
- case CFB:
- printf ("CFB;");
- printf (" Quantum is %d;", quant);
- break;
- default:
- printf ("Unknown;");
- break;
- }
- printf (" Key is %lx %lx;", keyl [0], keyl [1]);
- if (dmode != ECB) printf (" IV is %lx %lx;", iv [0], iv [1]);
- printf ("\n");
-
- flwid = (8 * 2) + 1; /* 8 bytes, 2 chars/byte, and a delimiter */
-
- while (eofyet == FALSE) /* until EOF detected on input */
- {
- if (dmode == ECB)
- {
- for (i = 0; i < 4; i++) /* 4 groups on a printable line */
- {
- if (TRUE == g_inbytes (8, inbbuf)) eofyet = TRUE;
- di_bytes (8, inbbuf, &iprline [flwid*i], &ihxline [flwid*i]);
- packbtol (&inbbuf[0], &plain[0]);
- packbtol (&inbbuf[4], &plain[1]);
- dodes (plain, crypt, ENCRYPT, ks);
- sprdltob (crypt[0], &otbbuf[0]);
- sprdltob (crypt[1], &otbbuf[4]);
- di_bytes (8, otbbuf, NULL, &ohxline [flwid*i]);
- if (TRUE == eofyet) break;
- }
- }
- else if (dmode == CBC)
- {
- for (i = 0; i < 4; i++) /* 4 groups on a printable line */
- {
- if (TRUE == g_inbytes (8, inbbuf)) eofyet = TRUE;
- di_bytes (8, inbbuf, &iprline [flwid*i], &ihxline [flwid*i]);
- packbtol (&inbbuf[0], &plain[0]);
- packbtol (&inbbuf[4], &plain[1]);
- plain [0] ^= iv [0]; /* XOR IV with input plaintext */
- plain [1] ^= iv [1];
- dodes (plain, crypt, ENCRYPT, ks);
- sprdltob (crypt[0], &otbbuf[0]);
- sprdltob (crypt[1], &otbbuf[4]);
- di_bytes (8, otbbuf, NULL, &ohxline [flwid*i]);
- iv [0] = crypt [0]; /* use ciphertext output as next IV */
- iv [1] = crypt [1];
- if (TRUE == eofyet) break;
- }
- }
- else if (dmode == CFB)
- {
- for (i = 0; i < 4; i++) /* 4 groups on a printable line */
- /* does file read and display in 64-bit units regardless of quantum */
- {
- if (TRUE == g_inbytes (8, inbbuf)) eofyet = TRUE;
- di_bytes (8, inbbuf, &iprline [flwid*i], &ihxline [flwid*i]);
- packbtol (&inbbuf[0], &plain[0]);
- packbtol (&inbbuf[4], &plain[1]);
- for (j = 0; j < 64; j+=quant)
- {
- dodes (iv, crypt, ENCRYPT, ks);
- rsh64 (crypt, 64-quant); /* right-align active DES output bits */
- cpy64 (plain, cprbuf); /* copy plaintext to scratch */
- rsh64 (cprbuf, 64-(quant+j)); /* right-align active plaintext bits */
- /* XOR them into DES output */
- crypt [0] ^= cprbuf [0]; crypt [1] ^= cprbuf [1];
- lsh64 (iv, quant); /* shift existing IV over */
- rplr64 (iv, crypt, quant); /* replace LS IV bits with DES output */
- lsh64 (cipher, quant); /* make space in cipher out array */
- rplr64 (cipher, crypt, quant); /* insert new output bits */
- }
- sprdltob (cipher[0], &otbbuf[0]);
- sprdltob (cipher[1], &otbbuf[4]);
- di_bytes (8, otbbuf, NULL, &ohxline [flwid*i]);
- if (TRUE == eofyet) break;
- }
- }
- else if (dmode == OFB)
- {
- for (i = 0; i < 4; i++) /* 4 groups on a printable line */
- {
- if (TRUE == g_inbytes (8, inbbuf)) eofyet = TRUE;
- di_bytes (8, inbbuf, &iprline [flwid*i], &ihxline [flwid*i]);
- packbtol (&inbbuf[0], &plain[0]);
- packbtol (&inbbuf[4], &plain[1]);
- for (j = 0; j < 64; j+=quant)
- {
- dodes (iv, crypt, ENCRYPT, ks);
- rsh64 (crypt, 64-quant); /* right-align active DES output bits */
- lsh64 (iv, quant); /* shift existing IV over */
- rplr64 (iv, crypt, quant); /* replace LS IV bits with DES output */
- cpy64 (plain, cprbuf); /* copy plaintext to scratch */
- rsh64 (cprbuf, 64-(quant+j)); /* right-align active plaintext bits */
- /* XOR them into DES output */
- crypt [0] ^= cprbuf [0]; crypt [1] ^= cprbuf [1];
- lsh64 (cipher, quant); /* make space in cipher out array */
- rplr64 (cipher, crypt, quant); /* insert new output bits */
- }
- sprdltob (cipher[0], &otbbuf[0]);
- sprdltob (cipher[1], &otbbuf[4]);
- di_bytes (8, otbbuf, NULL, &ohxline [flwid*i]);
- if (TRUE == eofyet) break;
- }
- }
- printf ("%s\n%s\n%s\n", iprline, ihxline, ohxline);
- }
- printf ("\n");
- }
-
- /* ------------------------------------------------------ */
- /* This DES software was developed by Steve Kent and John Linn */
- /* at BBN Communications Corporation, Cambridge, MA */
- /* Do not redistribute this software, or integrate with other */
- /* software, without preserving this notice */
- /* ------------------------------------------------------ */
-
-